package net.kucoe.grin.utils;

import java.lang.reflect.Method;
import java.util.*;

import org.objectweb.asm.*;

/**
 * Uses ASM for names info reading.
 * 
 * @author Vitaliy Basyuk
 */
public class VariableReader extends ClassVisitor {
    
    class MethodVariableReader extends MethodVisitor {
        
        public MethodVariableReader() {
            super(Opcodes.ASM4);
        }
        
        public void visitLocalVariable(final String name, final String desc, final String signature, final Label start,
            final Label end, final int index) {
            List<String> parameters = methodParameters.get(currentMethod);
            if (parameters == null) {
                parameters = new LinkedList<String>();
                methodParameters.put(currentMethod, parameters);
            }
            if (!"this".equals(name)) {
                parameters.add(name);
            }
        }
    }
    
    protected Map<String, List<String>> methodParameters = new HashMap<String, List<String>>();
    private String currentMethod;
    
    /**
     * Constructs VariableReader.
     */
    public VariableReader() {
        super(Opcodes.ASM4);
    }
    
    public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
        final String[] exceptions) {
        currentMethod = name + desc;
        return new MethodVariableReader();
    }
    
    /**
     * Returns method parameter names.
     * 
     * @param method
     * @return list
     */
    public List<String> getVariableNames(final Method method) {
        return methodParameters.get(method.getName() + Type.getMethodDescriptor(method));
    }
    
}
